package com.zwh.se.concurrency.lock;

/**
 * @author zwh
 * synchronized：被synchronized和static修饰的方法，锁的对象是类的class对象。
 * synchronized在jdk1.6中的优化：
 * 1、锁消除：在synchronized修饰的代码块中没有操作临界资源的话，java在编译的时候会把synchronized去掉
 * 2、锁膨胀：如果在在一个循环中，频繁的获取和释放锁资源，这样的消耗很大，锁膨胀就是把锁定范围扩大，避免频繁的竞争和索取锁资源带来的不必要的消耗
 * 3、锁升级：在JDK1.6中，Java引入了锁膨胀机制，当一个线程多次获取锁的时候，会自动将锁从偏向锁转化为轻量级锁，然后再转化为重量级锁。
 * 这样可以减少线程竞争和锁操作的开销，提高了多线程程序的性能。
 */
public class SynchronizedDemo {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
            try {
                phone1.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "Thread 1").start();
        new Thread(() -> {
            try {
                phone2.hello(); //没有锁会直接运行
                phone2.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "Thread 2").start();
    }
}

class Phone{
    public synchronized void sendSMS()throws Exception{
        System.out.println(Thread.currentThread().getName()+"\t -----invoked sendSMS()");
        Thread.sleep(3000);
        sendEmail();
    }

    public synchronized void sendEmail() throws Exception{
        System.out.println(Thread.currentThread().getName()+"\t +++++invoked sendEmail()");
    }
    public void hello(){
        System.out.println(Thread.currentThread().getName()+"\t +++++invoked hello()");
    }
}